Add native delivery for Codex and Claude - #254
Conversation
fbe9e14 to
0c9cf8a
Compare
|
Rollout finding: the old 6d Codex wrapper left its app-server process group alive after the owning PTY daemon stopped. The orphan stayed invisible until the 9f wrapper tried to replace it and correctly refused a second live control owner. A verified TERM of the exact old process group released the socket, and the 9f driver then recovered with a real bus round trip. A later doctor improvement should report a live Codex app-server group or socket that no current wrapper owns. This follow-up is recorded only; this PR does not add that doctor check. |
|
Rollout follow-up: the three hosts do not have one sanctioned binary transport. Droppy cannot build Rust. Pulling from Hetz failed because Droppy lacked inbound SSH authorization. A Hetz-to-Droppy push over Tailscale SSH worked, but it depended on a machine key. The synced catalog is not artifact storage and must not be used as a workaround. The fleet needs an owned artifact transport with integrity verification. |
|
macOS comparison against the PR base:
PR #254 fixes these three tests on macOS:
The remaining macOS failures exist on the base. Both full suites used |
Proven on a real Claude session: the rendered MCP declaration caused Claude to spawn the watcher as its child; killing Claude removed the watcher, with no st2 task or DING sidecar. A self-authored distinctive token reached the model, which replied with the exact body token and archived the original. The first token run was blocked by a nonexistent scratch sender identity, a test-rig defect rather than a transport defect. The watcher refreshes native presence in its session loop. Known limit: if Claude hangs without closing stdio, the watcher remains attached to that hung session; no external heartbeat or supervisor is added.
a5ea782 to
3687a0b
Compare
Nathan asked for the whole native delivery change in one pull request. This is it. It replaces #241, which is now closed and points here.
What this contains
Both harnesses, in one branch, on top of current
main.Codex gets a declared app-server delivery.
st2starts the Codex process throughst2 codex-app-server, binds the thread, and writes messages into the durable inbox.Claude gets an MCP inbox watcher that Claude owns. Claude spawns it as its own child and it dies with the session.
The last three commits are the Claude half and the presence fix:
5ad1a99Add Claude-owned MCP inbox watcher23e68daClarify Codex native ownership boundaryb184715Refresh Codex native presence from session loopThe specification stays separate in #242. #232 also stays separate, because it is a decision and not a patch.
The architecture, stated plainly
st2writes a file to the inbox. That is allst2does. A watcher observes the folder and sends into the provider's channel. The agent acts and archives, and the archive is the settlement.st2does not call the channel directly, for either harness. There is no cursor, no lease, no claim and no dedup table. A restart is just another start: it reads the folder, and anything still there is outstanding by definition.Opt-in
Nothing changes for an agent that does not declare it. Existing agents keep the ding until their declaration says otherwise.
macOS: this branch is at parity with
main, and it fixes a real Darwin defectEvery test on this branch passes on macOS except one, and that one fails on
maintoo.Measured on Darwin 25.6.0, Apple Silicon, full library suite:
That remaining test is not ours. It fails on
mainwith none of this work in the tree, and it isfiled separately as #255.
A real macOS delivery defect was found and fixed here
When a Codex app-server wrote its messages and exited promptly, macOS threw those messages away.
Darwin fails
setsockoptas soon as the peer is gone, so the control pump abandoned the connectionwith data still buffered and unread. Linux delivers buffered bytes after a close, so the pump read
on and bound normally — which is why CI, which is
ubuntu-latestonly, never saw it.The fix drains what already arrived before reporting the connection closed. A close is an
end-of-stream marker, not a stop signal. It took the affected test from 7 failures in 8 runs to 0
in 8.
Two fixture budgets were also raised, because they were sized for a quieter machine and timed out
under parallel Darwin scheduling. Both changes are inside
mod tests.How it was found
CI proves Linux only. Every failure here came from running the suite on a Mac, and each fix was
measured over matched samples of six to eight full runs before it was believed. Two of the commits
are diagnostics rather than fixes, and they are the reason the rest exist — three theories died
against them.